class_name MonsterAI
extends Node

## Monster AI控制器
## 负责处理monster的追踪、朝向和移动逻辑
## 遵循单一职责原则：只处理AI相关的行为控制

# AI状态
enum AIState {
	CHASE,  # 追踪状态
	SLOWED  # 减速状态
}

# 节点引用
@export var rigid_body: RigidBody3D
@export var detection_raycast: RayCast3D

# AI配置参数
@export var chase_speed: float = 3.0           # 正常追踪速度
@export var slowed_speed: float = 1.0          # 减速后的速度（chase_speed的1/3）
@export var rotation_speed: float = 8.0        # 转向速度

# 寻路相关参数
@export var pathfinding_update_interval: float = 0.5   # 寻路更新间隔（秒）
@export var path_follow_threshold: float = 0.8         # 路径点跟随阈值
@export var max_path_length: int = 50                  # 最大路径长度

# 内部状态
var current_state: AIState = AIState.CHASE
var player_node: Node3D = null
var slow_timer: float = 0.0
var is_slowed: bool = false

# 寻路相关状态
var navigation_agent: NavigationAgent3D = null
var pathfinding_timer: float = 0.0
var current_path: PackedVector3Array = []
var current_path_index: int = 0
var last_player_position: Vector3 = Vector3.ZERO

## 初始化AI
func _ready():
	# 延迟查找玩家节点，确保场景已加载完成
	call_deferred("_find_player_node")
	call_deferred("_setup_navigation")
	
	# 确保减速速度是正常速度的1/3
	slowed_speed = chase_speed / 3.0

## 设置导航系统
func _setup_navigation():
	# 创建NavigationAgent3D节点
	navigation_agent = NavigationAgent3D.new()
	navigation_agent.path_desired_distance = 0.5
	navigation_agent.target_desired_distance = 0.5
	navigation_agent.path_max_distance = 3.0
	
	# 将NavigationAgent添加到Monster节点
	if rigid_body:
		rigid_body.add_child(navigation_agent)
		
		# 设置导航地图
		if DataManager.map_rid.is_valid():
			navigation_agent.set_navigation_map(DataManager.map_rid)

## 寻找玩家节点
## 通过DataManager获取玩家引用
func _find_player_node():
	if DataManager.has_method("get_player") and DataManager.get_player():
		player_node = DataManager.get_player()
	else:
		# 备用方案：通过场景树查找
		var players = get_tree().get_nodes_in_group("player")
		if players.size() > 0:
			player_node = players[0]

## 物理更新
func _physics_process(delta):
	if not rigid_body or not player_node:
		return
	
	# 处理减速状态计时
	_update_slow_state(delta)
	
	# 更新寻路
	_update_pathfinding(delta)
	
	# 执行AI行为
	_execute_ai_behavior(delta)

## 更新减速状态
## @param delta: 帧间隔时间
func _update_slow_state(delta):
	if is_slowed:
		slow_timer -= delta
		if slow_timer <= 0.0:
			_end_slow_effect()

## 更新寻路系统
## @param delta: 帧间隔时间
func _update_pathfinding(delta):
	if not navigation_agent or not player_node:
		return
	
	# 更新寻路计时器
	pathfinding_timer += delta
	
	# 检查是否需要重新计算路径
	var player_position = player_node.global_position
	var position_changed = last_player_position.distance_to(player_position) > 1.0
	var should_update = pathfinding_timer >= pathfinding_update_interval or position_changed
	
	if should_update:
		_calculate_path_to_player()
		pathfinding_timer = 0.0
		last_player_position = player_position

## 计算到玩家的路径
func _calculate_path_to_player():
	if not navigation_agent or not player_node or not rigid_body:
		return
	
	var start_position = rigid_body.global_position
	var target_position = player_node.global_position
	
	# 使用NavigationAgent计算路径
	navigation_agent.target_position = target_position
	
	# 等待一帧让导航系统计算路径
	await get_tree().process_frame
	
	# 获取计算出的路径
	if navigation_agent.is_navigation_finished():
		current_path = []
		current_path_index = 0
	else:
		var nav_path = navigation_agent.get_current_navigation_path()
		if nav_path.size() > 0:
			current_path = nav_path
			current_path_index = 0
			# 移除起始点（当前位置）
			if current_path.size() > 1:
				current_path = current_path.slice(1)

## 获取下一个导航目标点
## @return Vector3: 下一个目标位置
func _get_next_navigation_target() -> Vector3:
	if current_path.is_empty():
		# 没有路径时直接朝向玩家
		return player_node.global_position if player_node else rigid_body.global_position
	
	# 检查是否到达当前路径点
	var current_position = rigid_body.global_position
	if current_path_index >= current_path.size():
		return Vector3.ZERO
	var target_point = current_path[current_path_index]
	
	# 忽略Y轴差异
	var distance_2d = Vector2(current_position.x - target_point.x, current_position.z - target_point.z).length()
	
	if distance_2d < path_follow_threshold:
		# 到达当前路径点，移动到下一个
		current_path_index += 1
		if current_path_index >= current_path.size():
			# 到达路径终点
			return player_node.global_position if player_node else current_position
		else:
			target_point = current_path[current_path_index]
	
	return target_point

## 执行AI行为
## @param delta: 帧间隔时间
func _execute_ai_behavior(delta):
	# 获取导航目标点
	var target_position = _get_next_navigation_target()
	
	# 计算到目标的方向
	var to_target = target_position - rigid_body.global_position
	to_target.y = 0  # 忽略Y轴差异，保持水平移动
	
	if to_target.length() < 0.1:
		return  # 距离太近，不需要移动
	
	var move_direction = to_target.normalized()
	
	# 计算目标旋转
	_rotate_towards_direction(move_direction, delta)
	
	# 应用移动
	_apply_movement(move_direction)

## 朝向指定方向旋转
## @param direction: 目标方向向量
## @param delta: 帧间隔时间
func _rotate_towards_direction(direction: Vector3, delta):
	if direction.length() < 0.1:
		return
	
	# 计算目标旋转角度
	var target_angle = atan2(direction.x, direction.z)
	var current_angle = rigid_body.rotation.y
	
	# 计算角度差并处理角度环绕
	var angle_diff = target_angle - current_angle
	while angle_diff > PI:
		angle_diff -= 2 * PI
	while angle_diff < -PI:
		angle_diff += 2 * PI
	
	# 平滑旋转到目标角度
	var rotation_amount = rotation_speed * delta
	if abs(angle_diff) < rotation_amount:
		rigid_body.rotation.y = target_angle
	else:
		rigid_body.rotation.y += sign(angle_diff) * rotation_amount

## 应用移动力
## @param direction: 移动方向向量
func _apply_movement(direction: Vector3):
	# 根据当前状态选择移动速度
	var current_speed = slowed_speed if is_slowed else chase_speed
	
	# 设置水平速度，保持Y轴速度不变
	var new_velocity = direction * current_speed
	new_velocity.y = rigid_body.linear_velocity.y
	
	rigid_body.linear_velocity = new_velocity

## 应用减速效果
## 被投掷物击中时调用
func apply_slow_effect():
	if is_slowed:
		# 如果已经在减速状态，重置计时器
		slow_timer = 0.5
	else:
		# 开始减速效果
		is_slowed = true
		slow_timer = 0.5
		current_state = AIState.SLOWED
		
	print("Monster被击中，开始减速效果")

## 结束减速效果
func _end_slow_effect():
	is_slowed = false
	current_state = AIState.CHASE
	print("Monster减速效果结束")

## 获取当前移动速度
## @return float: 当前移动速度
func get_current_speed() -> float:
	return slowed_speed if is_slowed else chase_speed

## 获取当前路径信息（调试用）
## @return Dictionary: 路径信息
func get_path_info() -> Dictionary:
	return {
		"path_length": current_path.size(),
		"current_index": current_path_index,
		"has_navigation_agent": navigation_agent != null,
		"navigation_finished": navigation_agent.is_navigation_finished() if navigation_agent else false
	}
